/*
 * Copyright (C) 2011 Consulanza Informatica.
 * info@consulanza.it
 *
 * This file is part of Customer Calls Tracker.
 *
 *    Customer Calls Tracker is free software: you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License as published
 *    by the Free Software Foundation, either version 3 of the License, or (at 
 *    your option) any later version.
 *
 *    Customer Calls Tracker is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General 
 *    Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with Customer Calls Tracker. If not, see http://www.gnu.org/licenses/.
 *
 * Portions of this software is a derivate work from:
 *
 * Copyright (C) 2008 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 * The DatabaseAssistant class is a derivate work from:
 * http://mgmblog.com/2009/02/06/export-an-android-sqlite-db-to-an-xml-file-on-the-sd-card/
 *
 */
package consulanza.amlsoft.customercalls;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

public class DatabaseAssistant {
    private static final String TAG = "DatabaseAssistant";

	private static final String EXPORT_FILE_NAME = "/sdcard/customercalls.xml";

	private Context _ctx;
	private SQLiteDatabase _db;
	private Exporter _exporter;

	/**
	 * 
	 * @param ctx
	 * @param db
	 */
	public DatabaseAssistant(Context ctx, SQLiteDatabase db) {
		_ctx = ctx;
		_db = db;

		try {
			// create a file on the sdcard to export the
			// database contents to
			File myFile = new File(EXPORT_FILE_NAME);
			myFile.createNewFile();

			FileOutputStream fOut = new FileOutputStream(myFile);
			BufferedOutputStream bos = new BufferedOutputStream(fOut);

			_exporter = new Exporter(bos);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			Log.e(TAG," Errore in apertura file Export", e);
		} catch (IOException e) {
			e.printStackTrace();
			Log.e(TAG," Errore in apertura file Export", e);
		} catch (Exception e) {
			e.printStackTrace();
			Log.e(TAG," Errore in apertura file Export", e);
		}
	}
	/**
	 * 
	 */
	public void exportData() {
		log("Exporting Data");

		try {
			_exporter.startDbExport(_db.getPath());

			// get the tables out of the given sqlite database
			String sql = "SELECT * FROM sqlite_master";

			Cursor cur = _db.rawQuery(sql, new String[0]);
			Log.d("db", "show tables, cur size " + cur.getCount());
			cur.moveToFirst();

			String tableName;
			while (cur.getPosition() < cur.getCount()) {
				tableName = cur.getString(cur.getColumnIndex("name"));
				log("table name " + tableName);

				// don't process these two tables since they are used
				// for metadata
				if (!tableName.equals("android_metadata")
						&& !tableName.equals("sqlite_sequence")) {
					exportTable(tableName);
				}

				cur.moveToNext();
			}
			_exporter.endDbExport();
			_exporter.close();
		} catch (IOException e) {
			e.printStackTrace();
			Log.e(TAG," Errore nell'Export: ", e);
		} catch (Exception e) {
			e.printStackTrace();
			Log.e(TAG," Errore nell'Export: ", e);
		}
	}
	/**
	 * 
	 * @param tableName
	 * @throws IOException
	 */
	private void exportTable(String tableName) throws IOException {
		_exporter.startTable(tableName);

		// get everything from the table
		String sql = "SELECT * FROM " + tableName;
		Cursor cur = _db.rawQuery(sql, new String[0]);
		int numcols = cur.getColumnCount();

		log("Start exporting table " + tableName);

		cur.moveToFirst();

		// move through the table, creating rows
		// and adding each column with name and value
		// to the row
		while (cur.getPosition() < cur.getCount()) {
			_exporter.startRow();
			String name;
			String val;
			for (int idx = 0; idx < numcols; idx++) {
				name = cur.getColumnName(idx);
				val = cur.getString(idx);
				log("col '" + name + "' -- val '" + val + "'");

				_exporter.addColumn(name, val);
			}

			_exporter.endRow();
			cur.moveToNext();
		}

		cur.close();

		_exporter.endTable();
	}
	/**
	 * 
	 * @param msg
	 */
	private void log(String msg) {
		Log.w(TAG, msg);
	}
	/**
	 * 
	 * @author amedeo
	 *
	 */
	class Exporter {
		private static final String TAG_DB_START	= "<export-database name='%s'>";
		private static final String TAG_DB_END		= "</export-database>";
		private static final String TAG_TABLE_START = "<table name='%s'>";
		private static final String TAG_TABLE_END	= "</table>";
		private static final String TAG_ROW_START	= "<row>";
		private static final String TAG_ROW_END		= "</row>";
		private static final String TAG_COLUMN		= "<col name='%s'>%s</col>";

		private BufferedOutputStream _bos;

		public Exporter() throws FileNotFoundException {
			this(new BufferedOutputStream(_ctx.openFileOutput(EXPORT_FILE_NAME,
					Context.MODE_WORLD_READABLE)));
		}

		public Exporter(BufferedOutputStream bos) {
			_bos = bos;
		}

		public void close() throws IOException {
			if (_bos != null) {
				_bos.close();
			}
		}

		public void startDbExport(String dbName) throws IOException {
			String stg = String.format(TAG_DB_START,dbName);
			_bos.write(stg.getBytes());
		}

		public void endDbExport() throws IOException {
			_bos.write(TAG_DB_END.getBytes());
		}

		public void startTable(String tableName) throws IOException {
			String stg = String.format(TAG_TABLE_START,tableName);
			_bos.write(stg.getBytes());
		}

		public void endTable() throws IOException {
			_bos.write(TAG_TABLE_END.getBytes());
		}

		public void startRow() throws IOException {
			_bos.write(TAG_ROW_START.getBytes());
		}

		public void endRow() throws IOException {
			_bos.write(TAG_ROW_END.getBytes());
		}

		public void addColumn(String name, String val) throws IOException {
			String stg = String.format(TAG_COLUMN,name,val);
			_bos.write(stg.getBytes());
		}
	}

}
